Spring Bean
1. 개요
1. 개요
Spring Bean은 Spring Framework의 핵심 구성 요소로, Spring IoC 컨테이너에 의해 생성되고 관리되는 객체를 의미한다. 애플리케이션을 구성하는 핵심 객체들을 Spring IoC 컨테이너가 제어하기 때문에, 개발자는 객체의 생성과 의존 관계 설정, 생명주기 관리에 대한 복잡성을 직접 처리하지 않아도 된다.
이러한 빈은 XML 설정, Java Config(@Configuration), 컴포넌트 스캔(@Component) 방식을 통해 컨테이너에 등록된다. 등록된 빈은 컨테이너에 의해 인스턴스화되고, 필요한 의존 관계가 주입되며, 초기화와 소멸의 생명주기를 관리받는다.
주요 역할을 표시하는 어노테이션으로는 일반 컴포넌트를 나타내는 @Component, 비즈니스 로직 계층의 @Service, 데이터 접근 계층의 @Repository, 웹 계층의 @Controller 등이 널리 사용된다. 또한 자바 설정 클래스 내에서 빈을 정의할 때는 @Bean 어노테이션이 활용된다.
2. 정의
2. 정의
Spring Bean은 Spring IoC 컨테이너가 생성과 소멸을 포함한 전 생애 주기를 관리하는 객체를 의미한다. 일반적인 자바 객체와 달리 개발자가 직접 new 키워드로 생성하지 않고, 스프링 프레임워크의 컨테이너에 의해 인스턴스화되고 의존성이 주입되며 관리된다.
이러한 빈 객체는 XML 설정 파일, 자바 설정 클래스(@Configuration), 또는 컴포넌트 스캔(@Component) 방식을 통해 컨테이너에 등록된다. 등록된 빈은 컨테이너가 필요 시점에 생성하고, 설정된 의존 관계에 따라 다른 빈을 주입하며, 초기화와 소멸 시점에 지정된 콜백 메서드를 실행하는 등 일련의 생명주기를 따르게 된다.
Spring Bean의 핵심은 제어의 역전과 의존성 주입 원칙을 구현하는 데 있다. 애플리케이션의 객체 간 결합도를 낮추고, 설정과 로직을 분리하여 테스트와 유지보수를 용이하게 한다.
3. 특징
3. 특징
Spring Bean의 가장 큰 특징은 Spring IoC 컨테이너에 의해 생성되고 관리된다는 점이다. 애플리케이션 개발자가 직접 객체를 생성(new)하는 것이 아니라, 컨테이너가 객체의 생성부터 의존 관계 설정, 생명주기 관리까지 전담한다. 이를 통해 객체 간의 결합도를 낮추고, 유연하고 테스트하기 쉬운 코드를 작성할 수 있다.
두 번째 특징은 다양한 방법으로 등록과 설정이 가능하다는 점이다. 초기에는 XML 설정 파일을 주로 사용했지만, 어노테이션 기반의 컴포넌트 스캔(@Component, @Service 등)과 자바 설정 클래스(@Configuration, @Bean)를 통한 방법이 표준으로 자리 잡았다. 이는 설정의 편의성과 가독성을 크게 향상시켰다.
마지막으로, Spring Bean은 명시적으로 정의된 스코프를 가진다. 기본값은 애플리케이션 전반에 걸쳐 단 하나의 인스턴스만 생성되어 공유되는 싱글톤 스코프이다. 이 외에도 요청이 올 때마다 새로운 객체를 생성하는 프로토타입 스코프, 웹 애플리케이션에서 HTTP 요청 또는 사용자 세션 단위로 생명주기가 관리되는 요청(Request) 스코프와 세션(Session) 스코프 등을 선택적으로 적용할 수 있다.
4. 생명주기
4. 생명주기
Spring Bean의 생명주기는 Spring IoC 컨테이너에 의해 관리되는 일련의 단계를 의미한다. 컨테이너는 빈 객체를 생성하고 의존성을 연결하며, 필요한 초기화 작업을 수행한 후 애플리케이션에서 사용할 수 있게 한다. 최종적으로 애플리케이션이 종료되면 컨테이너는 빈의 소멸 과정을 관리한다.
빈의 생명주기는 크게 다섯 단계로 구분된다. 첫 번째는 인스턴스화로, 컨테이너가 빈 정의에 따라 객체를 생성하는 단계이다. 두 번째는 의존성 주입 단계로, 생성된 객체에 필요한 다른 빈이나 값을 설정한다. 세 번째는 초기화 콜백 단계로, 모든 의존성 주입이 완료된 후 사용자 정의 초기화 로직이 실행된다. 네 번째는 사용 단계로, 완전히 구성된 빈이 애플리케이션 비즈니스 로직에 활용된다. 마지막으로 애플리케이션 종료 시 소멸 콜백 단계가 실행되어 사용자 정의 정리 로직이 수행된 후 빈이 소멸한다.
개발자는 초기화와 소멸 시점에 특정 로직을 실행하도록 콜백 메서드를 지정할 수 있다. 전통적인 Spring Framework에서는 InitializingBean과 DisposableBean 인터페이스를 구현하는 방법이 있었으나, 현재는 어노테이션 기반 방식을 더 선호한다. @PostConstruct 어노테이션을 메서드에 부여하면 초기화 콜백으로, @PreDestroy 어노테이션을 부여하면 소멸 콜백으로 동작한다. 또한 XML 설정이나 자바 설정 클래스에서 init-method 및 destroy-method 속성을 지정하는 방법도 사용 가능하다.
이러한 생명주기 관리 덕분에 개발자는 복잡한 객체 생성과 의존성 해결, 리소스 관리에 신경 쓰지 않고 비즈니스 로직 개발에 집중할 수 있다. 싱글톤 스코프의 빈은 일반적으로 애플리케이션 시작 시 생성되어 종료 시 소멸하는 반면, 프로토타입 스코프의 빈은 컨테이너가 소멸 과정을 관리하지 않는다는 점이 주요 차이점이다.
5. 스코프
5. 스코프
5.1. 싱글톤
5.1. 싱글톤
싱글톤 스코프는 스프링 프레임워크에서 빈의 기본 스코프이다. 이 스코프로 정의된 빈은 스프링 IoC 컨테이너당 정확히 하나의 객체 인스턴스만 생성된다. 컨테이너는 이 단일 인스턴스를 모든 해당 빈에 대한 요청과 참조에 재사용한다. 이는 GoF 디자인 패턴 중 하나인 싱글톤 패턴과 개념적으로 유사하지만, 중요한 차이점이 있다. 전통적인 싱글톤 패턴은 클래스 로더 수준에서 하나의 인스턴스를 보장하는 반면, 스프링의 싱글톤 스코프는 각 스프링 애플리케이션 컨텍스트 내에서 하나의 인스턴스를 보장한다. 따라서 동일한 웹 애플리케이션 내에 여러 개의 애플리케이션 컨텍스트가 존재한다면, 동일한 빈 정의에 대해 여러 개의 싱글톤 인스턴스가 생성될 수 있다.
싱글톤 빈은 애플리케이션 전반에 걸쳐 공유되는 상태 없는(Stateless) 서비스 객체나 DAO, 컨트롤러와 같은 컴포넌트를 정의하는 데 적합하다. 의존성 주입을 통해 다른 빈에 주입될 때마다 동일한 객체 참조가 전달되므로, 메모리 사용 효율이 높고 성능상의 이점을 가진다. 그러나 이는 동시에 상태 관리에 주의를 요구한다. 싱글톤 빈이 변경 가능한(Mutable) 인스턴스 변수를 가지고 있다면, 스레드 안전성 문제가 발생할 수 있기 때문이다. 따라서 싱글톤 빈을 설계할 때는 가능한 한 무상태로 유지하거나, 동기화 처리를 통해 스레드 안전을 보장해야 한다.
싱글톤 스코프는 명시적으로 지정하지 않아도 기본값으로 적용된다. XML 설정에서는 scope 속성을 생략하거나 "singleton"으로 명시하면 되며, 어노테이션 기반 설정에서는 @Scope 어노테이션을 생략하거나 @Scope("singleton")으로 정의한다. 컴포넌트 스캔을 통해 발견된 @Component, @Service, @Repository, @Controller가 붙은 클래스들은 별도의 스코프 지정이 없으면 모두 싱글톤으로 생성된다.
5.2. 프로토타입
5.2. 프로토타입
프로토타입 스코프는 스프링 프레임워크가 관리하는 빈의 한 종류로, 컨테이너로부터 빈을 요청할 때마다 매번 새로운 인스턴스를 생성하여 반환한다. 이는 기본 스코프인 싱글톤과 대비되는 특징이다. 싱글톤 빈이 애플리케이션 전반에 걸쳐 단 하나의 인스턴스만 공유되는 반면, 프로토타입 빈은 각 요청 시 독립적인 객체가 생성된다.
프로타입 빈의 생명주기는 일반적인 자바 객체와 유사하다. 스프링 IoC 컨테이너는 빈의 인스턴스화, 의존성 주입, 초기화 콜백까지의 과정만 수행하고, 이후 관리를 중단한다. 따라서 컨테이너는 프로토타입 빈의 소멸을 책임지지 않으며, 소멸 콜백도 호출되지 않는다. 생성된 객체의 소멸은 클라이언트 코드나 가비지 컬렉션에 맡겨진다.
프로토타입 스코프는 상태를 유지해야 하거나, 쓰레드에 안전하지 않은 객체를 사용할 때, 또는 빈의 생명주기가 매우 짧은 경우에 적합하다. 예를 들어, 각 HTTP 요청마다 독립적인 데이터를 처리해야 하는 비즈니스 객체나, 사용자 세션별로 상태가 달라지는 객체를 구현할 때 활용될 수 있다.
프로토타입 빈은 @Scope("prototype") 어노테이션을 @Component나 @Bean과 함께 사용하여 정의할 수 있다. 또한 XML 설정 파일에서는 <bean> 태그의 scope 속성을 "prototype"으로 지정하여 등록한다.
5.3. 요청
5.3. 요청
요청 스코프는 Spring Bean의 스코프 중 하나로, 하나의 HTTP 요청이 시작될 때 생성되고 해당 요청이 종료될 때 소멸되는 빈을 의미한다. 즉, 각각의 HTTP 요청마다 새로운 빈 인스턴스가 생성되어 요청 내에서 공유되며, 요청이 끝나면 인스턴스도 함께 제거된다. 이는 웹 애플리케이션에서 특정 요청에 종속적인 상태를 관리할 때 유용하다.
요청 스코프 빈은 주로 스프링 MVC 기반의 웹 애플리케이션에서 사용된다. 예를 들어, 사용자의 요청 정보나 세션 데이터를 임시로 담는 모델 객체, 요청별로 다른 설정이 필요한 컴포넌트, 또는 요청 처리 과정에서만 유효해야 하는 트랜잭션 관련 리소스를 정의할 때 적합하다. 싱글톤 스코프와 달리 각 요청이 독립된 인스턴스를 가지므로, 여러 사용자의 요청이 서로의 상태를 간섭하지 않는다는 장점이 있다.
요청 스코프를 사용하려면 빈 정의 시 @Scope("request") 어노테이션을 명시하거나, XML 설정에서는 scope="request" 속성을 지정한다. 또한 스프링 부트를 사용하는 웹 애플리케이션에서는 별도의 추가 설정 없이 요청 스코프를 사용할 수 있다. 이 스코프는 서블릿 컨테이너의 요청 생명주기와 밀접하게 연동되어 동작한다.
스코프 | 설명 | 생성 시점 | 소멸 시점 |
|---|---|---|---|
요청(request) | 하나의 HTTP 요청 내에서 공유되는 빈 | HTTP 요청 시작 시 | HTTP 요청 종료 시 |
세션(session) | 하나의 HTTP 세션 내에서 공유되는 빈 | HTTP 세션 생성 시 | HTTP 세션 종료 시 |
애플리케이션(application) | 하나의 서블릿 컨텍스트 내에서 공유되는 빈 | 웹 애플리케이션 시작 시 | 웹 애플리케이션 종료 시 |
5.4. 세션
5.4. 세션
세션 스코프는 하나의 HTTP 세션의 생명주기와 동일한 범위를 가지는 빈 스코프이다. 주로 웹 애플리케이션에서 사용되며, 사용자별로 독립적인 상태를 유지해야 하는 객체를 정의할 때 적합하다. 예를 들어, 사용자의 로그인 정보나 장바구니 데이터와 같은 세션 단위의 정보를 담는 객체를 이 스코프로 선언한다.
세션 스코프의 빈은 각 사용자의 세션이 생성될 때 인스턴스가 생성되어 해당 세션 내에서 싱글톤처럼 동작한다. 즉, 같은 세션 내의 여러 요청에서 동일한 빈 인스턴스를 공유하게 된다. 사용자의 세션이 종료되면(예: 로그아웃 또는 세션 타임아웃) 스프링 IoC 컨테이너는 해당 세션에 속한 빈 인스턴스의 소멸 콜백을 호출하고 인스턴스를 제거한다.
이 스코프를 사용하려면 빈 정의 시 스코프를 명시해야 한다. 자바 설정 클래스에서는 @Scope("session") 어노테이션을, XML 설정에서는 <bean> 태그의 scope 속성을 "session"으로 지정한다. 세션 스코프는 기본적으로 스프링 MVC와 같은 웹 애플리케이션 컨텍스트에서만 정상적으로 동작한다.
스코프 | 설명 | 유효 범위 |
|---|---|---|
session | HTTP 세션 당 하나의 인스턴스 생성 | 웹 애플리케이션, HTTP 세션 생명주기 |
5.5. 애플리케이션
5.5. 애플리케이션
애플리케이션 스코프는 Spring Bean의 스코프 중 하나로, 하나의 웹 애플리케이션 내에서 단 하나의 인스턴스만 생성되어 공유되는 범위를 의미한다. 이는 서블릿 컨텍스트 수준의 스코프로, 서블릿 컨텍스트가 시작될 때 생성되고 종료될 때 소멸된다. 따라서 웹 애플리케이션이 실행되는 동안 동일한 빈 인스턴스가 애플리케이션 전역에서 재사용된다.
애플리케이션 스코프는 싱글톤 스코프와 유사하게 하나의 인스턴스를 공유하지만, 그 범위가 다르다. 싱글톤 스코프의 빈은 하나의 Spring IoC 컨테이너당 하나의 인스턴스를 가지는 반면, 애플리케이션 스코프의 빈은 하나의 웹 애플리케이션당 하나의 인스턴스를 가진다. 이는 하나의 애플리케이션에 여러 개의 Spring IoC 컨테이너가 존재하는 경우 그 차이가 명확해진다.
이 스코프는 애플리케이션 전체에서 공통적으로 사용해야 하는 설정 정보나 유틸리티 객체, 캐시 매니저와 같은 인프라스트럭처 빈을 정의할 때 유용하다. 예를 들어, 애플리케이션 전체에 걸쳐 공유되는 캐시나 데이터베이스 연결 풀과 같은 자원을 관리하는 빈에 적합한 스코프이다.
애플리케이션 스코프의 빈을 정의하는 방법은 XML 설정이나 자바 설정 클래스를 사용하며, 스코프를 명시적으로 지정해야 한다. XML 설정에서는 scope="application" 속성을, 자바 설정 클래스에서는 @Scope("application") 어노테이션을 사용하여 설정할 수 있다.
6. 등록 방법
6. 등록 방법
6.1. XML 설정
6.1. XML 설정
Spring 빈을 등록하는 전통적인 방식으로, XML 파일을 사용하여 빈의 정의와 의존 관계를 명시적으로 기술한다. 초기 스프링 프레임워크에서 주로 사용되었으며, 애플리케이션의 구성 정보를 코드와 분리하여 관리할 수 있는 장점이 있다.
XML 설정 파일(일반적으로 applicationContext.xml 또는 beans.xml 등) 내부에서는 <beans>를 루트 엘리먼트로 사용하고, 각 빈은 <bean> 엘리먼트로 정의한다. 주요 속성으로는 빈을 고유하게 식별하는 id와 빈의 완전한 클래스 경로를 지정하는 class가 있다. 의존성 주입은 <constructor-arg>나 <property> 엘리먼트를 통해 수행된다.
설정 요소 | 설명 |
|---|---|
| 단일 빈을 정의한다. |
| 생성자 기반 의존성 주입을 설정한다. |
| 세터 기반 의존성 주입을 설정한다. |
| 지정된 패키지 내의 |
이 방식은 설정이 중앙 집중화되어 구조를 한눈에 파악하기 쉽지만, 파일이 커지면 관리가 복잡해지고 컴파일 타임에 오류를 검출하기 어렵다는 단점이 있다. 최근에는 어노테이션 기반 설정이나 자바 설정 클래스를 더 선호하는 추세이다.
6.2. 어노테이션
6.2. 어노테이션
Spring 프레임워크에서 빈을 정의하고 관리하기 위해 다양한 어노테이션을 제공한다. 이 어노테이션들은 주로 빈의 등록 방법과 역할을 명시하는 데 사용된다.
주요 컴포넌트 스캔 어노테이션으로는 @Component, @Service, @Repository, @Controller가 있다. 이들은 모두 스테레오타입 어노테이션으로 분류되며, 컴포넌트 스캔 과정에서 자동으로 빈으로 등록되는 대상이 된다. 각 어노테이션은 특정 계층이나 역할을 의미하며, @Component는 가장 일반적인 스테레오타입이고, @Service는 비즈니스 로직 계층, @Repository는 데이터 접근 계층, @Controller는 프레젠테이션 계층을 표시한다. 특히 @Repository는 데이터 접근 객체에 선언 시 퍼시스턴스 예외를 스프링의 통일된 데이터 접근 예외로 변환하는 부가 기능을 제공한다.
@Configuration과 @Bean 어노테이션은 자바 설정 클래스를 통한 빈 등록 방식에서 사용된다. @Configuration이 붙은 클래스는 빈 설정의 정보를 담고 있는 클래스임을 나타내며, 이 클래스 내부에서 @Bean 어노테이션이 붙은 메서드는 스프링 IoC 컨테이너에 의해 관리될 빈 객체를 반환한다. 이 방식은 XML 설정 파일을 대체하는 현대적인 방법이다. 또한, 의존성 주입을 지시하기 위한 @Autowired, @Qualifier, @Resource 등의 어노테이션도 빈의 관계를 구성하는 데 핵심적으로 활용된다.
6.3. 자바 설정 클래스
6.3. 자바 설정 클래스
자바 설정 클래스는 스프링 프레임워크 3.0부터 도입된 빈 등록 방식으로, XML 설정 파일 대신 자바 코드를 사용하여 스프링 IoC 컨테이너의 구성 정보를 정의한다. 이 방식의 핵심은 @Configuration 어노테이션을 클래스에 선언하는 것이다. @Configuration이 붙은 클래스는 빈의 구성 정보를 담는 설정 클래스가 되며, 내부에 @Bean 어노테이션이 붙은 메서드를 정의하여 빈을 등록한다.
@Bean 어노테이션은 메서드의 반환 객체를 스프링 IoC 컨테이너가 관리하는 빈으로 등록하도록 지시한다. 메서드 이름은 기본적으로 빈의 이름으로 사용되며, 필요에 따라 @Bean(name="customName") 형태로 이름을 지정할 수 있다. 이 방식의 장점은 자바 코드의 강력한 타입 안정성과 리팩토링 지원을 활용할 수 있으며, 의존성 주입(DI) 시 복잡한 객체 생성 로직이나 조건부 빈 등록을 프로그래밍적으로 쉽게 구현할 수 있다는 점이다.
자바 설정 클래스는 XML 설정과 함께 사용되거나, 또는 완전히 대체하여 사용될 수 있다. 스프링 부트(Spring Boot)는 내부적으로 이 방식을 광범위하게 채택하고 있어, 현대적인 스프링 애플리케이션 개발의 표준 방식으로 자리 잡았다. 설정 클래스 내에서는 다른 빈을 생성자나 메서드 파라미터로 주입받아 사용할 수 있어, 빈 간의 의존 관계를 명확하고 유연하게 구성할 수 있다.
7. 의존성 주입
7. 의존성 주입
7.1. 생성자 주입
7.1. 생성자 주입
생성자 주입은 Spring Bean에 필요한 의존 객체를 생성자를 통해 전달하는 방식이다. Spring IoC 컨테이너는 빈을 생성할 때 필요한 다른 빈들을 생성자의 매개변수로 자동으로 주입한다. 이 방식은 객체가 생성되는 시점에 모든 의존성이 확보되도록 강제하기 때문에, 주입된 의존성이 변하지 않는 불변 객체를 만들 수 있다는 장점이 있다.
생성자 주입은 주로 필수적인 의존성을 설정할 때 사용된다. @Autowired 어노테이션을 생성자 위에 명시할 수 있으며, Spring Framework 4.3 버전 이후부터는 생성자가 하나뿐일 경우 해당 어노테이션을 생략해도 자동으로 주입이 수행된다. 이 방식은 의존성 주입이 한 번만 이루어지므로 런타임 중에 의존성이 변경될 위험이 없으며, 순환 참조와 같은 문제를 사전에 발견하는 데도 도움이 된다.
다음은 생성자 주입을 사용한 간단한 예시이다.
```java
@Service
public class OrderService {
private final PaymentProcessor paymentProcessor;
@Autowired
public OrderService(PaymentProcessor paymentProcessor) {
this.paymentProcessor = paymentProcessor;
}
}
```
위 코드에서 OrderService 빈이 생성될 때, Spring IoC 컨테이너는 PaymentProcessor 타입의 빈을 찾아 생성자의 인자로 주입한다. final 키워드를 사용함으로써 의존성의 불변성을 보장할 수 있다. 생성자 주입은 테스트 코드 작성 시에도 Mock 객체를 주입하기 용이하여 단위 테스트의 편의성을 높인다.
7.2. 세터 주입
7.2. 세터 주입
세터 주입은 스프링 프레임워크에서 의존성 주입을 구현하는 주요 방식 중 하나이다. 이 방식은 빈 클래스에 의존 객체를 설정(set)하는 전용 메서드, 즉 세터 메서드를 정의하고, 스프링 IoC 컨테이너가 런타임에 해당 메서드를 호출하여 필요한 의존성을 주입하는 것을 말한다.
세터 주입은 주로 선택적 의존성이나 런타임 중에 변경될 가능성이 있는 의존성을 처리할 때 유용하다. XML 설정을 사용하는 경우, 빈 정의 내 <property> 요소를 통해 이름(name)과 참조(ref) 또는 값(value)을 지정하여 주입할 대상을 명시한다. 자바 설정 클래스에서는 @Bean 메서드 내에서 해당 객체의 세터 메서드를 직접 호출하는 방식으로 구현할 수 있다.
주입 방식 | 설명 | 설정 예 (XML) |
|---|---|---|
세터 주입 | 세터 메서드를 통해 의존성 주입 |
|
세터 주입은 생성자 주입에 비해 객체 생성 후 의존성을 설정할 수 있어 유연성이 높다는 장점이 있지만, 객체가 완전히 초기화되지 않은 상태(의존성이 주입되지 않은 상태)로 사용될 수 있는 가능성이 있다는 단점도 있다. 따라서 최근에는 객체의 불변성을 보장하고 필수 의존성을 명확히 하는 생성자 주입을 권장하는 경향이 있다.
7.3. 필드 주입
7.3. 필드 주입
필드 주입은 Spring Framework에서 의존성 주입을 수행하는 방법 중 하나로, 클래스의 필드에 직접 의존성을 주입하는 방식을 말한다. @Autowired 어노테이션을 필드 위에 선언함으로써 Spring IoC 컨테이너가 해당 타입의 빈을 찾아 자동으로 할당한다. 이 방법은 코드가 매우 간결해진다는 장점이 있어 빠른 프로토타이핑이나 간단한 테스트에 유용하게 사용된다.
그러나 필드 주입은 몇 가지 심각한 단점을 가지고 있다. 첫째, 생성자나 세터 메서드를 사용하지 않기 때문에 의존 관계를 외부에서 변경하거나 목 객체로 대체하는 것이 불가능하다. 이는 단위 테스트를 어렵게 만든다. 둘째, 필드가 final로 선언될 수 없어 불변성을 보장할 수 없다. 셋째, 리플렉션을 통해 주입이 이루어지기 때문에 프레임워크에 강하게 결합된다.
이러한 이유로 Spring 공식 문서와 많은 개발 커뮤니티에서는 생성자 주입을 권장한다. 생성자 주입은 필드를 final로 선언해 불변성을 보장하고, 테스트 용이성을 높이며, 의존 관계를 명확하게 드러낼 수 있다. 필드 주입은 레거시 코드나 특정 서드파티 라이브러리와의 통합과 같이 제한된 경우에만 고려하는 것이 바람직하다.
8. 관련 어노테이션
8. 관련 어노테이션
Spring 프레임워크에서 빈을 정의하고 관리하기 위해 사용되는 주요 어노테이션은 다음과 같다. 이 어노테이션들은 주로 빈의 등록 방법과 역할에 따라 구분된다.
컴포넌트 스캔을 통해 빈을 자동으로 등록하는 데 사용되는 스테레오타입 어노테이션에는 @Component, @Service, @Repository, @Controller가 있다. @Component는 모든 스프링 빈의 기본이 되는 가장 일반적인 어노테이션이다. @Service, @Repository, @Controller는 각각 비즈니스 로직 계층, 데이터 접근 계층, 프레젠테이션 계층을 명시적으로 표현하기 위한 @Component의 특수화된 형태이다. 이들은 계층 구조를 명확히 하고, @Repository의 경우 데이터 접근 객체에 대한 예외 변환과 같은 추가적인 기능을 제공할 수 있다.
반면, 자바 설정 클래스 내에서 빈을 명시적으로 정의할 때 사용하는 어노테이션이 @Bean이다. 이 어노테이션은 메서드 레벨에 적용되며, 해당 메서드가 반환하는 객체를 스프링 IoC 컨테이너가 관리하는 빈으로 등록하도록 지시한다. @Bean 어노테이션은 주로 외부 라이브러리의 클래스나 설정을 빈으로 등록해야 할 때, 또는 인스턴스 생성 과정에 특별한 로직이 필요할 때 유용하게 사용된다.
어노테이션 | 주요 용도 | 적용 위치 |
|---|---|---|
| 일반적인 컴포넌트(빈) 자동 등록 | 클래스 |
| 서비스 계층의 빈 자동 등록 | 클래스 |
| 데이터 접근 계층(DAO)의 빈 자동 등록 | 클래스 |
| MVC의 컨트롤러 빈 자동 등록 | 클래스 |
| 자바 설정 클래스 내에서 빈 명시적 정의 | 메서드 |
이 외에도 빈의 의존성 주입을 위해 @Autowired, @Resource, @Inject 어노테이션이 사용되며, 빈의 스코프를 지정하는 @Scope, 지연 로딩을 설정하는 @Lazy 등의 어노테이션도 빈의 동작을 세밀하게 제어하는 데 활용된다.
9. 여담
9. 여담
Spring Bean은 스프링 프레임워크의 핵심 개념으로, IoC 컨테이너에 의해 관리되는 객체를 의미한다. 이는 단순히 자바에서 new 키워드로 생성하는 일반 객체와는 구분된다. 컨테이너가 객체의 생성부터 의존성 주입, 생명주기 관리까지 전담함으로써 개발자는 비즈니스 로직에 더 집중할 수 있고, 느슨한 결합과 테스트 용이성을 얻을 수 있다.
초기 스프링에서는 XML 설정 파일을 통해 Bean을 정의하는 것이 표준 방식이었다. 이는 설정과 코드를 분리한다는 장점이 있었지만, 설정 파일이 방대해지고 가독성이 떨어지는 단점도 있었다. 이후 어노테이션 기반 설정(@Component, @Service 등)과 자바 설정 클래스(@Configuration, @Bean)가 도입되면서, 보다 직관적이고 타입 안전한 Bean 등록 방식이 주류를 이루게 되었다.
Bean의 다양한 스코프(싱글톤, 프로토타입, 요청, 세션 등)는 애플리케이션의 요구사항에 맞춰 객체의 생명주기와 존재 범위를 세밀하게 제어할 수 있게 해준다. 특히 싱글톤 스코프는 메모리 효율성으로 인해 가장 널리 사용되며, 프로토타입 스코프는 매번 새로운 인스턴스가 필요한 경우에 유용하다.
Spring Bean의 개념은 의존성 주입 패턴을 실천하는 구체적인 수단이다. 이를 통해 제어의 역전 원칙이 실현되며, 이는 스프링 프레임워크가 가진 모듈화와 유연성의 근간이 된다.
